package com.mrdeer.config.aspect;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;

/**
 * @author xie jianchu
 */
@Slf4j
@Aspect
@Component
public class ServiceLogAspect {
    /**
     * 切面表达式
     * exception 代表所要执行的表达式主体
     * 第一处 * 代表方法返回类型 * 代表所有类型
     * 第二处 报名代表aop监控的类所在的包
     * 第三处 ..代表该报以及其子包下的所有类方法
     * 第四处 * 代表类名 *代表所有类
     * 第五处 *(..) * 代表类中的方法名,(..)表示方法中的任何参数
     *
     * @param joinPoint
     * @return
     * @throws Throwable
     */
    @Around("execution(* com.mrdeer.web.service.sys.impl..*.*(..))")
    public Object recordTimeLog(ProceedingJoinPoint joinPoint) throws Throwable {
        log.info("======开始执行{}.{}======", joinPoint.getTarget().getClass());

        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        long begin = System.currentTimeMillis();
        Object result = joinPoint.proceed();
        log.info("<============================================================>");
        log.info("请求来源:" + request.getRemoteAddr());
        log.info("请求URL:" + request.getRequestURL().toString());
        log.info("请求方式:" + request.getMethod());
        log.info("响应方法:" + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
        log.info("请求参数:" + Arrays.toString(joinPoint.getArgs()));
        long end = System.currentTimeMillis();
        long takeTime = end - begin;
        if (takeTime > 3000) {
            log.error("=========执行结束，耗时:{}毫秒=========", takeTime);
        } else if (takeTime > 2000) {
            log.warn("=========执行结束，耗时:{}毫秒=========", takeTime);
        } else {
            log.info("=========执行结束，耗时:{}毫秒=========", takeTime);
        }
        log.info("<------------------------------------------------------------>");
        return result;
    }
}
